<?php

/**
 * Auth - Gestisce l'autenticazione dell'utente
 *
 * @author Gigi Pastore (gigi@la-fabbrica.org)
 * @package    LaFabbrica
 * @copyright  Copyright (c) 2014 Luigi Pastore
 * @author luigi.pastore
 * @created  15-mag-2014
 */
class Classes_Core_Auth
{
    private $db = NULL;
    private $config = array();
    private $sql = '';
    private $result = NULL;

    /**
     * Constructor
     */
    function __construct()
    {
	// Connessione DB...
	$this->db = Classes_Core_MySqliLayer::getInstance();

	$this->session_id = isset( $_COOKIE['reg_session'] ) ? $_COOKIE['reg_session'] : NULL;

	$this->config['expire'] = 60 * 60 * 3; # 3 ore
    }

    //*-------------------------------------------------------------------------*/
    // Viene utilizzata per prelevare un array di due valori avente come primo valore
    // lo stato dell'utente che sta navigando la pagina e come secondo una lista di informazioni
    // relative all'utente, in caso questi sia connesso.
    // Per prima cosa vengono eliminate le sessioni scadute, poi viene recuperato l'ID univoco.
    // Se questo non è presente, significa che l'utente non ha ancora effettuato il login
    // o che la sua sessione è scaduta.
    // Se invece esiste, vengono prelevate dal database le informazioni relative all'utente e restituite.
    /* ------------------------------------------------------------------------- */
    public function getStatus()
    {
	// Eliminiamo le sessioni precedenti...
	$this->cleanExpired();

	// restituisce l'ID univoco relativo alla sessione corrente
	if( is_null( $this->session_id ) )
	    return array( 100, NULL );

	$this->sql = 'SELECT *
				FROM reg_users
				LEFT JOIN reg_sessions ON reg_sessions.`user_id` = reg_users.`user_id`
				WHERE reg_users.`user_id` = reg_sessions.`user_id` AND reg_sessions.`session_id` = \'' . $this->session_id . '\'';

	# Esegui Query...
	$this->result = $this->db->query( $this->sql );

	if( $this->result->num_rows != 1 )
	{
	    return array( 100, NULL );
	}
	else
	{
	    $data = $this->result->fetch_assoc();
	    return array( 99, $data, $data['session_id'] );
	}
    }

    //*-------------------------------------------------------------------------*/
    // Viene utilizzata per eliminare le sessioni scadute precedentemente.
    // Viene richiamata in ogni pagina dalla funzione auth_get_status().
    // L'eliminazione della sessione avviene semplicemente eliminando dal database i record relativi
    // a sessioni scadute, ed eliminando l'ID di riferimento salvato.
    /* ------------------------------------------------------------------------- */
    private function cleanExpired()
    {
	$this->sql = 'SELECT session_creation_date FROM reg_sessions WHERE `session_id` = \'' . $this->session_id . '\'';

	# Esegui Query...
	$this->result = $this->db->query( $this->sql );

	if( $this->result )
	{
	    $this->data = $this->result->fetch_assoc();

	    if( $this->data['creation_date'] )
		if( $this->data['creation_date'] + $this->config['expire'] <= time() )
		    setcookie( 'reg_session_id', '', 0, '/' );
	}

	$this->sql = 'DELETE FROM reg_sessions WHERE `session_creation_date` + ' . $this->config['expire'] . ' <= ' . time();

	# Esegui Query...
	$this->result = $this->db->query( $this->sql );
    }

    /* ------------------------------------------------------------------------- */
    // Effettua il login: accetta come parametri l'username e la password esegue una query di selezione
    // per controllare che i dati permettano il login di un utente.
    // In caso affermativo restituisce lo status AUTH_LOGEDD_IN ed i dati dell'utente,
    // in caso negativo restituisce AUTH_INVALID_PARAMS e nessun altra informazione.
    /* ------------------------------------------------------------------------- */
    public function login( $umail, $passw )
    {
//		$this->sql = 'SELECT reg_users.user_id
//				FROM reg_users
//				WHERE reg_users.`user_email` = \''. $this->db->clean( $umail ) . '\'
//				AND reg_users.`user_password` = MD5(\''. $this->db->clean( $passw ) . '\')';

	$this->sql = array( 'reg_users', // data[0]
	    array( '*' ), // data[1]
	    array( 'reg_users.`user_email`' => $umail, // data[2]
		'reg_users.`user_password`' => md5( $passw ) ), // data[3]
	    array( 'reg_user_groups' => array( 'reg_users.`user_group_id`', 'reg_user_groups.`group_id`' ) )
	);

	# Esegui Query...
	$this->result = $this->db->simpleSelectQuery( $this->sql );

	if( $this->result )
	    return $this->result->num_rows != 1 ? array( AUTH_INVALID_PARAMS, NULL ) : array( AUTH_LOGGED_IN, $this->result->fetch_assoc() );

	return $this->db->error();
    }

    //*-------------------------------------------------------------------------*/
    // Accetta come parametri i dati di un utente che si suppone autenticato precedentemente,
    // e genera una nuova sessione;
    // inserisce nella tabella delle sessioni le informazioni necessarie, e restituisce un array:
    // in caso l'operazione sia andata a buon fine restituir� lo status AUTH_LOGEDD_IN e l'ID della sessione,
    // altrimenti AUTH_FAILED e null'altro
    /* ------------------------------------------------------------------------- */
    public function registerSession( $udata )
    {
	$this->session_id = $this->generateUniqueId();

	# Insert reg_session
	$sql_data[0] = array( 'reg_sessions',
	    array( 'session_id' => $this->session_id,
		'session_user_id' => $udata['user_id'],
		'session_creation_date' => time() ) );
	
	# Update reg_users
	$sql_data[1] = array( 'reg_users',
	    array( 'user_lastlogin' => date('Y-m-d H:i:s') ),
	    array( 'user_id' => $udata['user_id'] ) );

	# Esegui Query...
	return ( is_int( $this->db->insertQuery( $sql_data[0] ) ) AND $this->db->updateQuery( $sql_data[1] ) ) ? array( AUTH_LOGGED_IN, $this->session_id ) : array( AUTH_FAILED, $this->db->error() );
    }

    //*-------------------------------------------------------------------------*/
    // Esegue il logout dell'utente connesso
    /* ------------------------------------------------------------------------- */
    function logout()
    {
	if( !is_null( $this->session_id ) AND is_int( $this->db->deleteQuery( array( 'reg_sessions', array( 'session_id' => $this->session_id ) ) ) ) )
	    return true;
	else
	    return false;
    }

    //*-------------------------------------------------------------------------*/
    // Genera un ID univoco di 32 caratteri, sfruttando funzioni builtin di PHP.
    /* ------------------------------------------------------------------------- */
    private function generateUniqueId()
    {
	list( $usec, $sec ) = explode( ' ', microtime() );
	mt_srand( (float) $sec + ( (float) $usec * 100000 ) );
	return md5( uniqid( mt_rand(), true ) );
    }

}

?>